let Xi i = ([1..i]) |> List.map (fun i -> "x" + i.ToString())
let Yi i = ([1..i]) |> List.map (fun i -> "y" + i.ToString())

let x = Xi 4
let y = Yi 4
let fns = [
    "Head"      , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , (Xi i).Head )  ;
    "Tail"      , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "(" + ( (Xi i).Tail |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")")  ;
    "Last"      , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , ( (Xi i) |> List.rev |> List.head ) ) ;
    "Cons"      , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "fun x -> (x," +   ( (Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")" ) ;
    "Rev"       , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "(" +   ( (Xi i) |> List.rev |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")" ) ;
    "Map"       , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "fun x -> (x " + ( (Xi i) |> List.reduce (fun x1 x2 ->  x1 + "," + "x " + x2 ) ) + ")" ) ;
    "ApplyAll"     , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "fun ("   + ( (Yi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) )  + ") -> "+ (List.zip (Xi i) (Yi i) |> List.map (fun (x,y) -> x + " " + y) |> List.reduce (fun x1 x2 -> x1 + "," + x2 )) )  ;
    "ApplySingle",fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "fun x -> (" +    ( (Xi i) |> List.reduce (fun x1 x2 ->  x1 + " x," + x2) ) + " x)" ) ;
    "Fold"      , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "fun (x,y) -> " +    ( (Xi i) |> List.fold (fun x1 x2 -> "(x " +  x1  + x2+ ") ") "y " )  ) ;
    "Curry"     , fun i -> ( "x:"+ ((Xi i) |> List.map (fun x1-> "_" ) |> List.reduce (fun x1 x2 ->  x1 + "*" + x2 )) + "->_" , "fun "+( (Xi i) |> List.reduce (fun x1 x2 -> x1 + " " + x2 ) )+" -> x (" +   ( (Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")" ) ;
    "ToList"    , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "[" +    ( (Xi i) |> List.reduce (fun x1 x2 ->  x1 + ";" + x2) ) + "]" ) ;
    "ToSeq"     , fun i -> ( "(" + ((Xi i) |> List.reduce (fun x1 x2 -> x1 + "," + x2 ) ) + ")"  , "seq [" +    ( (Xi i) |> List.reduce (fun x1 x2 ->  x1 + ";" + x2) ) + "]" ) 
    ]


let printOp (name,code) i = 
    printfn "type %s() =  " name   
    ( [2..i] |> List.map ( fun i -> printfn "    static member ( *** ) (i:%s,%s)  = %s" name (fst (code i)) (snd (code i)) ) )